package com.itany.corejava.code08_常用类.string;

/**
 * @author MissChen
 * @version 1.0
 * @date 2023 年11月13日 14:40
 */
public class Test16_常量池 {
    public static void main(String[] args) {
        //通过构造方法创建的字符串，都是存储在堆内存中
        // 在堆中开辟了一块空间，值为admin
        String s=new String("admin");

        //在堆中重新开辟了一块空间，值为alice
        // 由于上一个admin的空间没有被任何对象所引用，其引用计数为0
        // 因此等待被gc销毁
        s=new String("alice");


        //此时又会在堆中开辟一块新的空间，值为admin
        String s2=new String("admin");

        // 通过双引号创建的字符串都是存储在常量池中
        // 在常量池中开辟一块新的空间，值为admin
        String s3="admin";

        // 在常量池中开辟一块新的空间，值为alice
        s3="alice";

        // 由于常量池中已经存在admin的空间
        // 因此s4没有开辟新的空间，而是直接指向原有的admin空间
        String s4="admin";

        String s5=new String("admin");
        // s2与s5所在的空间地址不同，则为false
        System.out.println(s2==s5);

        String s6="admin";

        //s4与s6都在常量池中，处于同一块空间，值为true
        System.out.println(s4==s6);

        String s7="a";
        String s8="aa";
        String s9="aaa";


        //s10不是字符常量，其值是运行时候确定的，而不是通过双引号给的
        // 当运行前不确定的值是不会被存储到常量池中的
        // 因此，此时s10是被存储在堆中的
        String s10=s7+s8;

        System.out.println(s9==s10);//false

        // 由于此时运行之前已经能够确定所有的值，因此直接存储到常量池中
        String s11="a"+"aa";
        System.out.println(s9==s11);//true

        String s12="a"+s8;
        System.out.println(s9==s12);//false

        // 堆中开辟了6块空间
        // 常量池中开辟了5块空间



    }
}
